package com.ht.WeNas.rest_controller;

import cn.hutool.core.util.StrUtil;
import com.ht.WeNas.common.Range;
import com.ht.WeNas.data.dto.FileObj;
import com.ht.WeNas.data.enumObj.UserType;
import com.ht.WeNas.data.vo.Res;
import com.ht.WeNas.data.vo.ResPage;
import com.ht.WeNas.service.FileService;
import com.ht.WeNas.utils.RequestFileUtil;
import com.ht.WeNas.utils.exceptions.MessageException;
import com.ht.WeNas.utils.tag.RequireUserType;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.nio.file.Path;
import java.util.List;

@RestController
@Slf4j
@Tag(name = "文件控制器")
@RequestMapping("/api/file")
public class FileController {
    private final FileService fileService;

    public FileController(FileService fileService) {
        this.fileService = fileService;
    }

    @RequireUserType(UserType.Admin)
    @GetMapping("/info")
    @Operation(summary = "获取文件信息")
    public Res<FileObj> getFileObjByPath(
            @Parameter(description = "路径")
            @RequestParam("path")
            String path
    ) {
        Path p = Path.of(path);
        return Res.ok(FileObj.getInstance(p));
    }

    @RequireUserType(UserType.Admin)
    @GetMapping()
    @Operation(summary = "获取文件")
    public void getFileByPath(
            @Parameter(description = "路径") @RequestParam("path") String path,
            HttpServletRequest request,
            HttpServletResponse response
    ) {
        FileObj fileObj = FileObj.getInstance(Path.of(path));
        if (fileObj == null) {
            throw new MessageException("文件访问失败");
        }
        Range range = RequestFileUtil.getRange(request);
        if (range == null) {
            RequestFileUtil.returnFile(fileObj, response);
            return;
        }
        RequestFileUtil.returnFileRange(fileObj, response, range, null);
    }

    @RequireUserType(UserType.Admin)
    @GetMapping("/dir")
    @Operation(summary = "获取文件夹内容")
    public Res<ResPage<FileObj>> getDirByPath (
            @Parameter(description = "路径")
            @RequestParam(value = "path")
            String path,
            
            @Parameter(description = "单页数据条数")
            @RequestParam(value = "size", required = false)
            Integer size,
            
            @Parameter(description = "页码")
            @RequestParam(value = "current", required = false)
            Integer current
    ) {
        if ("/".equals(path)) {
            List<FileObj> homeDir = fileService.getHomeDir();
            ResPage<FileObj> resPage = new ResPage<>(1, homeDir.size(), homeDir.size(), homeDir);
            return Res.ok(resPage);
        }
        if (size == null || size > 200) size = 200;
        if (size < 1) size = 10;
        if (current == null || current < 1) current = 1;
        return Res.ok(fileService.pageDirByPath(path, current, size));
    }

    @RequireUserType(UserType.Admin)
    @GetMapping("/m3u8")
    @Operation(summary = "传入ts文件路径，获取其m3u8")
    public String getM3U8(@Parameter(description = "文件地址") @RequestParam("path") String path) {
        FileObj fileObj = FileObj.getInstance(Path.of(path));
        if (fileObj == null) {
            throw new MessageException("文件访问失败");
        }
        return this.fileService.getM3U8String(fileObj);
    }

    @RequireUserType(UserType.Admin)
    @GetMapping("/m3u8/stream")
    @Operation(summary = "根据m3u8获取ts视频片段")
    public void streamM3U8(
            @Parameter(description = "开始bit位") @RequestParam("start") long start,
            @Parameter(description = "bit长度") @RequestParam("length") long length,
            @Parameter(description = "文件链接") @RequestParam("path") String path,
            HttpServletResponse response) {
        if (StrUtil.isBlank(path)) {
            throw new MessageException("请求参数为空");
        }
        try {
            this.fileService.streamM3U8(path, start, length, response.getOutputStream());
        } catch (IOException ignore) {}
    }
}
